home *** CD-ROM | disk | FTP | other *** search
-
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <winb.h>
- #include <te.h>
- #include <fntb.h>
- #include <gui.h>
- #include <file_dlg.h>
- #include <tifflib.h>
- #include <egb.h>
- #include <mos.h>
- #include <snd.h>
-
- #include "makemov.h"
-
- #define MALLOC TL_malloc
- #define FREE TL_free
-
- static struct {
- int frame;
- int total_byte;
- int rough;
- int premove;
- int x0,y0,x1,y1;
- int b,r,g;
- int soft;
- int color_rate, mode; // 外部からいじってはだめ
- int wait;
- } svar = { 0,0,0,0, 0,0,319,239, 0,0,0, 0,0,0, 0 };
-
- /*
- 外部に必要な関数:
- int LoadFrame(char *buf, int nFrame, int *nWidth, int *nHeight);
- // buf : 320×240×2バイトのバッファ
- // nFrame : フレーム番号(0~ total-1)
- // *nWidth, *nHeight : 用意したフレームの大きさを格納する
- // (or NULL)
- 返り値: 0=フレームの用意ができた -1:失敗
- */
-
- static int nFrameWid, nFrameHt;
- static char *pImageBuf;
- static int scount0;
-
- static char *rbuf,*bbuf;
-
- #define GETRGB(pixel, r,g,b) \
- { \
- b = (pixel) & 0x1f; \
- r = ((pixel) >> 5) & 0x1f; \
- g = ((pixel) >> 10) & 0x1f; \
- }
-
- #define INTSWAP(a,b) {int t=a; a=b; b=t;}
-
- /*--------------------------------------------------------*/
- /* pImageBuf の内容にソフトネスをかける */
- /*--------------------------------------------------------*/
-
- int mov_save_soft( char *buffer )
- // pImageBuf(320*240,word array) の内容にソフトネスをかけ、
- // 結果を buffer(320*240,word array) に出力
- // buffer: 320*240*2 bytes buffer
- // ソフトネスをかけた結果の出力先
- {
- int x,y;
- for ( y=svar.y0 ; y<=svar.y1 ; y++ )
- {
- for( x=svar.x0 ; x<=svar.x1 ; x++ )
- {
- int b,r,g;
- int n;
- b = r = g = 0;
- n = 0;
- // 各原色の強さの和をもとめる
- int ix,iy;
- for (iy=y-1; iy<=y+1; iy++)
- {
- if (iy < 0 || 240 <= iy)
- continue;
- for ( ix=x-1; ix<=x+1; ix++ )
- {
- if (0 <= ix && ix < 320)
- {
- int pix;
- pix = WORD(pImageBuf+iy*640+ix*2);
- b += ( pix & 0x1f );
- r += ( ( pix >> 5 ) & 0x1f );
- g += ( ( pix >> 10 ) & 0x1f );
- n++;
- }
- }
- }
- // 平均値を計算
- if (n > 0)
- {
- b = ( b + (b % n ) ) / n;
- r = ( r + (r % n ) ) / n;
- g = ( g + (g % n ) ) / n;
- }
- // 1ピクセルの計算結果をバッファに書き込む
- WORD( buffer+y*640+x*2 ) = b + (r << 5) + (g << 10);
- }
- }
- return 0;
- }
-
- /*--------------------------------------------------------*/
- /* pImageBuf の絵に、buffer の内容をかぶせる */
- /*--------------------------------------------------------*/
-
- int mov_save_filter( int flt, char *buffer )
- {
- int x, y, flt1, flt2, flt3;
- int filt[][19] = {
- { -9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9 },
- { -9,-8,-7,-6,-5,-4,-3,-2, 0,0,0,2,3,4,5,6,7,8,9 },
- { -9,-8,-7,-6,-5,-4,-3,-1, 0,0,0,1,3,4,5,6,7,8,9 },
- { -9,-8,-7,-6,-5,-4,-2,-1, 0,0,0,1,2,4,5,6,7,8,9 },
- { -9,-8,-7,-6,-5,-4,-2, 0, 0,0,0,0,2,4,5,6,7,8,9 },
- { -9,-8,-7,-5,-4,-2,-1, 0, 0,0,0,0,1,2,4,5,7,8,9 },
- };
- int f1[] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5 };
- int f2[] = { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5 };
- int f3[] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5 };
- /* フィルター */
- if ( flt < 0 )
- flt = 0;
- if ( flt > 15 )
- flt = 15;
- flt1 = f1[ flt ];
- flt2 = f2[ flt ];
- flt3 = f3[ flt ];
- if (flt > 0)
- {
- for (y=svar.y0; y<=svar.y1; y++)
- {
- for (x=svar.x0; x<=svar.x1; x++)
- {
- int idx = y*640 + x*2; /* buffer add */
- int px1,px2;
- int r1,g1,b1,r2,g2,b2;
- px1 = WORD( buffer+idx );
- px2 = WORD( pImageBuf+idx );
- GETRGB(px1,r1,g1,b1);
- GETRGB(px2,r2,g2,b2);
- if ((b2-b1 > -10) && (b2-b1 < 10) )
- b2 = b1 + filt[ flt1 ][b2-b1+9];
- if ((r2-r1 > -10) && (r2-r1 < 10) )
- r2 = r1 + filt[ flt2 ][r2-r1+9];
- if ((g2-g1 > -10) && (g2-g1 < 10) )
- g2 = g1 + filt[ flt3 ][g2-g1+9];
- WORD(pImageBuf+idx) = b2 + (r2 << 5) + (g2 << 10);
- }
- }
- }
- return 0;
- }
-
- /*--------------------------------------------------------*/
- /* pImageBuf の、指定範囲の外側をクリアする */
- /*--------------------------------------------------------*/
-
- int mov_save_trim( cmpmode )
- int cmpmode;
- {
- int color, x, y;
- color = svar.b + (svar.r << 5) + (svar.g << 10);
- int i;
- // 最上位ビットをクリア
- for (i=0; i<320*240*2; i+=4)
- DWORD( rbuf+i ) &= 0x7fff7fff;
- for (i=0; i<320*240*2; i+=4 )
- DWORD( pImageBuf+i ) &= 0x7fff7fff;
- // 範囲指定値の整合性チェック
- if (svar.x0 > svar.x1)
- INTSWAP(svar.x0, svar.x1);
- if (svar.y0 > svar.y1)
- INTSWAP(svar.y0, svar.y1);
- if (svar.x0 == 0 && svar.y0 == 0 && svar.x1 == 319 && svar.y1 == 239)
- return 0;
- //
- for ( y=0 ; y < 240 ; y++ )
- {
- for ( x=0 ; x < 320 ; x++ )
- {
- if (x < svar.x0 || svar.x1 < x || y < svar.y0 || svar.y1 < y)
- {
- int i = y*640 + x*2; /* buffer add */
- if ( cmpmode != 0 )
- {
- WORD(rbuf +i) |= 0x8000;
- WORD(pImageBuf+i) ^= (unsigned int)0xffff;
- }
- else
- WORD(pImageBuf+i) = color;
- }
- }
- }
- return 0;
- }
-
-
- mov_save_end( namemov )
- char *namemov;
- {
- FILE *fps;
- int i, temp, data[2];
-
- if( svar.frame == 0 )
- return 0;
- for( i=0 ; i<6 ; i++ ){ /* disk write protect の場合6回必要 */
- if( ( fps = fopen( namemov, "r+b" ) ) != NULL )goto save2;
- }
- return 2;
- save2:
- data[0] = svar.total_byte;
- data[1] = svar.frame; /* data長 page */
- fseek( fps, 8, SEEK_SET );
- temp = fwrite( (char *)data, 8, 1, fps );
- fclose( fps );
- if( temp < 1 ){
- /* remove( namemov ); error */
- return 2;
- }
- return 0;
- }
-
- /*--------------------------------------------------------*/
- /* 圧縮処理のサブルーチン群 */
- /*--------------------------------------------------------*/
-
- /* 平均化したデータをrbufに書き込む */
-
- int mov_save_stosw1_write( p )
- int p;
- {
- int i, j, k, n, m, data, addre1, addre2, len;
- int a1, a2, vadd;
-
- data = WORD( bbuf + p ) | 0x8000;
- p += 2;
- n = WORD( bbuf + p );
- p += 2;
- if( n ){
- for( i=0 ; i<n ; i++ ){
- addre1 = WORD( bbuf + p ) << 16;
- p += 2;
- m = WORD( bbuf + p );
- p += 2;
- if( m ){
- for( j=0 ; j<m ; j++ ){
- addre2 = addre1 + WORD( bbuf + p );
- p += 2;
- len = BYTE( bbuf + p );
- p += 1;
- if( len == 0xff ){
- len = WORD( bbuf + p );
- p += 2;
- }
- if( len == 0xffff ){
- len = DWORD( bbuf + p );
- p += 4;
- }
- if( len ){
- for( k=0 ; k<len ; k++ ){
- WORD( rbuf + addre2 + k*2 ) = data;
- }
- }
- /* 両端okなら処理済みに */
- k = addre2 - 2;
- if( k > 0 && k < 153600 ){
- vadd = ( (k/640) << 10 ) + ( k % 640 );
- a1 = WORD(pImageBuf + k);
- a2 = WORD(rbuf + k);
- if (mov_save_cmp_data(a1, a2, svar.rough) == 0
- && (a2 & 0x8000) == 0 )
- {
- WORD(rbuf + k) = a2 | 0x8000;
- WORD(pImageBuf + k) ^= 0xffff;
- }
- }
- k = addre2 + len*2;
- if( k > 0 && k < 153600 ){
- vadd = ( (k/640) << 10 ) + ( k % 640 );
- a1 = WORD(pImageBuf+k);
- a2 = WORD( rbuf+k );
- if( mov_save_cmp_data( a1, a2, svar.rough ) == 0
- && (a2 & 0x8000) == 0 ){
- WORD( rbuf+k ) = a2 | 0x8000;
- WORD(pImageBuf+k) ^= 0xffff;
- }
- }
- }
- }
- }
- }
- return 0;
- }
-
- /* store 最初にdataを読み込むtype & data平均化付き(1992 1.17) */
-
- int mov_save_stosw1( i )
- int i;
- {
- int p1, p2, p3, p4, p5, p6;
- int j, j1, j2, j3;
- int k, k1;
- int data;
- int a1, a2;
- int n1, n2, n3;
- int bt, rt, gt, nt, dt; /* data 平均値用 変数 */
-
- WORD( bbuf+i ) = 0x1222; i+=2; /* stosw brock */
- p1 = i; i+=4; /* size point */
- p2 = i; i+=2; /* data count point */
- n1 = 0; /* data count */
- for( j1=0 ; j1<153600 ; j1+=2 ){
- if( WORD( rbuf+j1 ) & 0x8000 )goto stos03; /* 処理済skip */
- data = WORD(pImageBuf+j1);
- if(
- mov_save_skip_check6( data, j1 )
- )goto stos03; /* skip check */
- bt = 0; rt = 0; gt = 0; nt = 0; /* for data 平均 */
- p3 = i; /* data top point */
- WORD( bbuf+i ) = data; i+=2; /* data */
- p4 = i; i+=2; /* offset count point */
- n2 = 0; /* offset count */
- for( j2=0 ; j2<3 ; j2++ ){ /* offset loop */
- p5 = i; /* offset top point */
- WORD( bbuf+i ) = j2; i+=2; /* offset */
- p6 = i; i+=2; /* d-address count point */
- n3 = 0; /* d-address count */
- k = 0; k1 = 0; /* data長count係数 */
- for( j3=0x10000*j2 ; j3<0x10000*(j2+1) ; j3+=2 ){
- if( j3 >= 153600 )break;
- a2 = WORD( rbuf+j3 );
- if( a2 & 0x8000 ){ /* 処理済skip */
- if( k ){
- i = i + k1;
- k = 0; k1 = 0;
- }
- goto stos01;
- }
- j = ( (j3/640) << 10 ) + ( j3 % 640 );
- a1 = WORD(pImageBuf+j3);
- if( (a2 & 0x8000) == 0 /* 手つかず */
- && mov_save_cmp_data( data, a1, svar.rough ) == 0
- /* 同色と認め */
- ){
- if( k == 0 )if(
- mov_save_skip_check4(data,j3)
- )goto stos01;
- k++;
-
- /* for data 平均 */
- bt = bt + ( a1 & 0x1f );
- rt = rt + ( (a1 >> 5) & 0x1f );
- gt = gt + ( (a1 >> 10) & 0x1f );
- nt++;
-
- WORD( rbuf+j3 ) = 0x8000 | data; /* 処理印 */
- WORD(pImageBuf+j3) ^= 0xffff;
- if( k == 1 ){
- n3++;
- WORD( bbuf+i ) = ( j3 & 0xffff );
- }
- if( k<0xff ){
- BYTE( bbuf+i+2 ) = k;
- k1 = 1+2;
- }
- if( (k>=0xff) && (k<0xffff) ){
- BYTE( bbuf+i+2 ) = 0xff;
- WORD( bbuf+i+3 ) = k;
- k1 = 3+2;
- }
- if( k>=0xffff ){
- BYTE( bbuf+i+2 ) = 0xff;
- WORD( bbuf+i+3 ) = 0xffff;
- DWORD( bbuf+i+5 ) = k;
- k1 = 7+2;
- }
- }
- else {
- if( k ){
- i = i + k1;
- k = 0; k1 = 0;
- }
- }
- stos01: ;
- }
- stos02: i = i + k1;
- WORD( bbuf+p6 ) = n3;
- if( n3 )n2++;
- else i = p5;
- }
- WORD( bbuf+p4 ) = n2;
- if( n2 ){
- n1++;
-
- if( nt ){ /* for data 平均 */
- dt = ( (bt + bt % nt) / nt )
- + ( ( (rt + rt % nt) / nt ) << 5 )
- + ( ( (gt + gt % nt) / nt ) << 10 );
- WORD( bbuf + p3 ) = dt;
- mov_save_stosw1_write( p3 );
- }
-
- }
- else i = p3;
- stos03: ;
- }
- WORD( bbuf+p2 ) = n1;
- if( n1 == 0 )i = p2;
- DWORD( bbuf+p1 ) = i - p2;
- return i;
- }
-
- int mov_save_skip_check2( data, n )
- int data, n;
- { /* 4つdataと同じ色が続くもの以外はスキップ */
- int a, b, i, j, k;
-
- if( n > 153588 )return 1;
- if( WORD( rbuf+n ) & 0x8000 )return 1;
- for( i=0 ; i<4 ; i++ ){
- k = n + (i << 1);
- a = WORD(pImageBuf+k);
- b = WORD( rbuf + k );
- if( mov_save_cmp_data( data, a, svar.rough) )return 1;
- }
- return 0;
- }
-
- /* skip_check1 = 1:skip ( for stosw ) */
-
- int mov_save_skip_check4( data, n )
- int data, n;
- { /* 4つdataと同じ色が続くもの以外はスキップ */
- int a, b, i, j, k;
-
- if( n > 153588 )return 1; /* ↓処理済直後はok */
- if( n && ( (DWORD( rbuf+n-2 ) & 0x80008000) == 0x8000 ) )return 0;
- if( WORD( rbuf+n ) & 0x8000 )return 1;
- for( i=0 ; i<4 ; i++ ){
- k = n + (i << 1);
- j = ( (k/640) << 10 ) + ( k % 640 );
- a = WORD(pImageBuf+k);
- b = WORD( rbuf + k );
- if( b & 0x8000 )return 0;
- if( mov_save_cmp_data( data, a, svar.rough) )return 1;
- }
- return 0;
- }
-
- int mov_save_skip_check6( data, n )
- int data, n;
- { /* 6つdataと同じ色が続くもの以外はスキップ */
- int a, b, i, j, k;
-
- if( n > 153588 )return 1;
- if( DWORD( rbuf+n ) & 0x80008000 )return 1;
- if( DWORD( rbuf+n+4 ) & 0x80008000 )return 1;
- if( DWORD( rbuf+n+8 ) & 0x80008000 )return 1;
- for( i=0 ; i<6 ; i++ ){
- k = n + (i << 1);
- j = ( (k/640) << 10 ) + ( k % 640 );
- a = WORD(pImageBuf+k);
- b = WORD( rbuf + k );
- if( mov_save_cmp_data( data, a, svar.rough) )return 1;
- }
- return 0;
- }
-
- /* movsw */
-
- int mov_save_movsw( i )
- int i;
- {
- int p1, p4, p5, p6;
- int j, j2, j3, j4;
- int k, k1, k2;
- int a1, a2;
- int n2, n3;
-
- WORD( bbuf+i ) = 0x2222; i+=2; /* movsw brock */
- p1 = i; i+=4; /* size point */
- p4 = i; i+=2; /* offset count point */
- n2 = 0; /* offset count */
- for( j2=0 ; j2<3 ; j2++ ){ /* offset loop */
- p5 = i; /* offset top point */
- WORD( bbuf+i ) = j2; i+=2; /* offset */
- p6 = i; i+=2; /* d-address count point */
- n3 = 0; /* d-address count */
- k = 0; k1 = 0; /* data長count係数 */
- for( j3=0x10000*j2 ; j3<0x10000*(j2+1) ; j3+=2 ){
- if( j3 >= 153600 )break;
- j = ( (j3/640) << 10 ) + ( j3 % 640 ); /* vram add */
- a1 = WORD(pImageBuf+j3); a2 = WORD( rbuf+j3 );
- if( (a2 & 0x8000) == 0 ){
- k++;
- WORD( rbuf+j3 ) = 0x8000 | a1; /* 処理印 */
- WORD(pImageBuf+j3) ^= 0xffff;
- if( k == 1 ){
- n3++;
- k2 = j3; /* address記憶 */
- WORD( bbuf+i ) = ( j3 & 0xffff );
- }
- if( k<0xff ){
- BYTE( bbuf+i+2 ) = k;
- k1 = 1+2;
- }
- if( (k>=0xff) && (k<0xffff) ){
- BYTE( bbuf+i+2 ) = 0xff;
- WORD( bbuf+i+3 ) = k;
- k1 = 3+2;
- }
- if( k>=0xffff ){
- BYTE( bbuf+i+2 ) = 0xff;
- WORD( bbuf+i+3 ) = 0xffff;
- DWORD( bbuf+i+5 ) = k;
- k1 = 7+2;
- }
- }
- else {
- if( k ){
- i = i + k1;
- k = 0; k1 = 0;
- for( j4=k2 ; j4<j3 ; j4+=2 ){ /* data write */
- WORD( bbuf+i ) = WORD( rbuf+j4 ) & 0x7fff;
- i+=2;
- }
- }
- }
- movs01: ;
- }
- movs02: if( k ){
- i = i + k1;
- k = 0; k1 = 0;
- for( j4=k2 ; j4<j3 ; j4+=2 ){ /* data write */
- WORD( bbuf+i ) = WORD( rbuf+j4 ) & 0x7fff;
- i+=2;
- }
- }
- WORD( bbuf+p6 ) = n3;
- if( n3 )n2++;
- else i = p5;
- }
- WORD( bbuf+p4 ) = n2;
- if( n2 == 0 )i = p4;
- DWORD( bbuf+p1 ) = i - p4;
- return i;
- }
-
- /* move box ( 16*16dot )指定されたboxを転送 */
-
- int mov_save_movebox16( i )
- int i;
- {
- int p1, p2, n;
- int j, j2, j3;
- int xmin, xmax, ymin, ymax, x, y, x1, y1, x2, y2, kx, ky, d;
- int max, a, a1, a2, b, r, g, cr, cb, yu, temp, temp2;
- int bfaddr, rbaddr, vraddr;
- char *offset1, *offset2;
- char vyuv[1024]; /* vram YUV data */
-
- offset1 = bbuf+0x1000; /* 旧画面データをchar *offset1にもう1枚作る */
- for( j=0 ; j<153600 ; j+=4 )DWORD( offset1+j ) = DWORD( rbuf+j );
- offset2 = bbuf+0x30000; /* 旧画面データのYUV data */
- /* rgb data (offset1) を yuv data (offset2) に */
- for( j=0 ; j<76800 ; j++ ){
- a = WORD( offset1 + (j << 1) );
- b = a & 0x1f;
- r = (a >> 5) & 0x1f;
- g = (a >> 10) & 0x1f;
- /* G,R,BをY,Cr,Cbに変換 */
- cr = -107*g + 128*r - 21*b + 3968; /* 0~256*31 */
- cb = -85*g - 43*r + 128*b + 3968;
- yu = ( 150*g + 77*r + 37*b ) >> 4;
- /* Cr(8), Cb(8), Y(16) */
- DWORD( offset2 +(j << 2) )
- = (cr >> 5) + ((cb << 3)& 0x0ff00) + (yu << 16);
- }
-
- WORD( bbuf+i ) = 0x3010; i+=2; /* move box 16 */
- p1 = i; i+=4; /* size point */
- p2 = i; i+=2; /* data 個数 count point */
- n = 0; /* data 個数 count */
- /* trimming area を はずすためのもの */
- xmin = 16*( svar.x0/16 ); if( svar.x0%16 )xmin += 16;
- xmax = 16*( svar.x1/16 ); if( svar.x1%16 == 15 )xmax += 1;
- ymin = 16*( svar.y0/16 ); if( svar.y0%16 )ymin += 16;
- ymax = 16*( svar.y1/16 ); if( svar.y1%16 == 15 )ymax += 1;
- for( y=ymin ; y<ymax ; y+=16 ){
- for( x=xmin ; x<xmax ; x+=16 ){
- /* vram YUV */
- vraddr = y*1024 + x*2; /* vram address */
- j = 0; /* count vyuv */
- for( j2=0 ; j2<16 ; j2++ ){
- for( j3=0 ; j3<32 ; j3+=2 ){
- a = WORD(pImageBuf+(y+j2)*640+x*2+j3);
- b = a & 0x1f;
- r = (a >> 5) & 0x1f;
- g = (a >> 10) & 0x1f;
- /* G,R,BをY,Cr,Cbに変換 */
- cr = -107*g + 128*r - 21*b + 3968; /* 0~256*31 */
- cb = -85*g - 43*r + 128*b + 3968;
- yu = ( 150*g + 77*r + 37*b ) >> 4;
- /* Cr(8), Cb(8), Y(16) */
- DWORD( vyuv +j )
- = (cr >> 5) + ((cb << 3) & 0x0ff00) + (yu << 16);
- j+=4;
- }
- vraddr += 1024;
- }
- temp2 = mov_save_cmp_box16( offset2, x, y, vyuv, svar.rough );
- if( temp2 > 255-8 ) { goto mov02; }
- max = temp2;
- kx = x; ky = y;
- /* ずらして調べる */
- x1 = x; y1 = y;
- for( d=svar.premove ; d>0 ; d-- ){
- for( j2 = -1 ; j2 <= 1 ; j2++ ){
- for( j3 = -1 ; j3 <= 1 ; j3++ ){
- x2 = x1 + j3*d;
- y2 = y1 + j2*d;
- if( x2 < 0 )x2 = 0; /* はみ出しを切る */
- if( x2 > 304 )x2 = 304;
- if( y2 < 0 )y2 = 0;
- if( y2 > 224 )y2 = 224;
- temp
- = mov_save_cmp_box16(
- offset2, x2, y2, vyuv, svar.rough );
- if( temp > max ){
- max = temp;
- kx = x2; ky = y2;
- }
- }
- }
- x1 = kx; y1 = ky;
- }
- /* 大まかに調べる */
- x1 = x - 32; if( x1 < 0 )x1 = 0;
- x2 = x + 32; if( x2 > 304 )x2 = 304;
- y1 = y - 32; if( y1 < 0 )y1 = 0;
- y2 = y + 32; if( y2 > 224 )y2 = 224;
- for( j2 = x1 ; j2 <= x2 ; j2+=16 ){
- for( j3 = y1 ; j3 <= y2 ; j3+=16 ){
- temp
- = mov_save_cmp_box16( offset2, j2, j3, vyuv, svar.rough );
- if( temp > max ){
- max = temp;
- kx = j2; ky = j3;
- }
- }
- }
- if( max > temp2+8 ){
- DWORD( bbuf+i ) = y*640 + x*2; i+=4;
- WORD( bbuf+i ) = kx; i+=2;
- WORD( bbuf+i ) = ky; i+=2;
- n++;
- bfaddr = ky*640 + kx*2; /* offset1 相対 address */
- rbaddr = y*640 + x*2; /* rbuf 相対 address */
- vraddr = y*1024 + x*2; /* vram address */
- for( j2=0 ; j2<16 ; j2++ ){
- for( j3=0 ; j3<32 ; j3+=2 ){
- a1 = WORD(pImageBuf+(y+j2)*640+x*2+j3);
- a2 = WORD( offset1+bfaddr+j3 ) & 0x7fff;
- WORD( rbuf+rbaddr+j3 ) = a2;
- if( mov_save_cmp_data( a1, a2, svar.rough ) == 0
- && (a1 & 0x8000) == 0 ){
- WORD( rbuf+rbaddr+j3 ) = a2 | 0x8000;
- WORD(pImageBuf+(y+j2)*640+x*2+j3) ^= 0xffff;
- }
- }
- bfaddr+=640; rbaddr+=640; vraddr+=1024;
- }
- mov02: ;
- }
- }
- }
- WORD( bbuf+p2 ) = n;
- if( n == 0 )i = p2;
- DWORD( bbuf+p1 ) = i - p2;
- return i;
- }
-
- /* YUV data buffer の char buffer(320*240)[開始座標(x,y)]と
- char *vyuv(16*16)の中でYUV判定で同じものを数える */
-
- int mov_save_cmp_box16( buffer, x, y, vyuv, rate )
- char *buffer, *vyuv;
- int x, y, rate;
- {
- int d1, d2, i, j, n, rate2;
-
- buffer = buffer + 1280*y + 4*x;
- n = 0; rate2 = rate*rate;
- for( j=0 ; j<16 ; j++ ){
- for( i=0 ; i<64 ; i+=4 ){
- d1 = (WORD( buffer+i+2 ) - WORD( vyuv+2 ));
- if( d1 > rate )goto cmp01;
- if( d1 < -rate )goto cmp01;
- d1 = BYTE( buffer+i ) - BYTE( vyuv );
- d2 = BYTE( buffer+i+1 ) - BYTE( vyuv+1 );
- if( d1*d1 + d2*d2 <= rate2 )n++;
- cmp01: vyuv += 4;
- }
- buffer += 1280;
- }
- return n;
- }
-
- /* Y,Cr,CbによるCOLCOR DATA比較法 91 7 24 */
-
- int mov_save_cmp_data( a, b, rate )
- int a, b, rate;
- {
- int b1,r1,g1, b2,r2,g2, d1, d2;
-
- if( (a & 0x7fff) == (b & 0x7fff) )return 0; /* 明白なものは処理 */
- else if( rate == 0 )return 1;
- /* G,R,B算出 */
- b1 = a & 0x1f; b2 = b & 0x1f;
- r1 = (a >> 5) & 0x1f; r2 = (b >> 5) & 0x1f;
- g1 = (a >> 10) & 0x1f; g2 = (b >> 10) & 0x1f;
- /* G,R,BをY,Cr,Cbに変換 & 判定 */
- d1 = ( 150*(g2 - g1) + 77*(r2 - r1) + 37*(b2 - b1) ) >> 4;
- if( d1 > rate )return 1;
- if( d1 < -rate )return 1;
- d1 = ( -107*(g2-g1) + 128*(r2-r1) - 21*(b2-b1) ) >> 5;
- d2 = ( -85*(g2 -g1) - 43*(r2 -r1) + 128*(b2 -b1) ) >> 5;
- if( d1*d1 + d2*d2 > rate*rate )return 1;
- else return 0;
- }
-
- /*--------------------------------------------------------*/
- /* 圧縮の心臓部 */
- /*--------------------------------------------------------*/
-
- int mov_save_page( char *pszMovName )
- {
- static int softAdjust[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15};
- static int filtAdjust[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15};
-
- int x,y;
- int cmpmode;
- FILE *fps;
- // int i, j, k, n, x, y, data, temp;
- // int xmin, ymin, xmax, ymax;
- // int a1, a2;
- int scount1;
- //, cmpmode ;
- // char para[64] ;
- char hread[256]; /* for head read */
- // /* mov head */
- char MovHead[256];
- static int MovHeadInit[] = { 0x32564f4d, 16, 0, 0, 320, 240, 640 };
- int pghead[8];
-
- // x0 < x1, y0 < y1 になるようにチェック
- if ( svar.x0 > svar.x1 )
- INTSWAP(svar.x0, svar.x1);
- if ( svar.y0 > svar.y1 )
- INTSWAP(svar.y0, svar.y1);
- // 前の絵と同じ点をカウント
- scount1 = 0;
- for ( y = svar.y0 ; y <= svar.y1 ; y++ )
- {
- for( x = svar.x0 ; x <= svar.x1 ; x++ )
- {
- int i = y*640 + x*2;
- if (mov_save_cmp_data(WORD(rbuf+i),WORD(pImageBuf+i),
- svar.rough) == 0)
- scount1++;
- }
- }
- cmpmode = ((scount1 < (scount0 >> 1)) ? 0 : 1);
- scount0 = scount1;
- // ソフトネスをかける
- if ( svar.soft > 0 )
- {
- mov_save_soft( bbuf );
- mov_save_filter( softAdjust[ svar.soft ], bbuf );
- }
-
- // ヘッダを出力
- if ( svar.frame == 0 )
- {
- svar.frame = 0;
- svar.total_byte = 0;
- cmpmode = 0;
- scount0 = (svar.x1-svar.x0+1) * (svar.y1-svar.y0+1) / 8;
- /* 次回から1/16以上同じなら差分 */
- int k;
- for( k=0 ; k<256 ; k++ )
- MovHead[k] = (char)0;
- for( k=0 ; k<7 ; k++ )
- DWORD( MovHead+k*4 ) = MovHeadInit[k];
- DWORD(MovHead + 28 ) = svar.wait;
- WORD( MovHead + 32 ) = svar.x0;
- WORD( MovHead + 34 ) = svar.y0;
- WORD( MovHead + 36 ) = svar.x1;
- WORD( MovHead + 38 ) = svar.y1;
- MovHead[150] = (char)1; /* タイミングフラグを表示してウエイト */
- if ((fps=fopen(pszMovName, "wb")) == NULL)
- return 2;
- fwrite( MovHead, 256, 1, fps );
- fclose( fps );
- }
- // 画面のはみ出した部分をclear
- mov_save_trim( cmpmode ); /* trimming */
- // リフレッシュ
- int temp; // エラーコード
- if ( cmpmode == 0 )
- {
- int k;
- // 最多色検索
- for (k=0; k<32768; k++)
- DWORD( rbuf+k*4 ) = 0;
- for (k=0; k<320*240; k++)
- {
- int data = WORD(pImageBuf+k*2);
- DWORD(rbuf+data*4) += 1;
- }
- int cnt; // 色の出現数
- int nCol; // もっともよく現れる色
- cnt = 0;
- nCol = 0;
- for( k=0 ; k<32768 ; k++ )
- if ( DWORD(rbuf+k*4) > cnt )
- cnt = DWORD(rbuf+k*4), nCol = k;
- // 塗りつぶし
- for (k=0; k<320*240*2; k+=2)
- {
- WORD(rbuf+k) = nCol;
- if (mov_save_cmp_data(nCol,WORD(pImageBuf+k),svar.rough) == 0)
- {
- WORD(rbuf+k) = nCol | 0x8000; /* 処理印 */
- WORD(pImageBuf+k) ^= (unsigned int)0xffff;
- }
- }
- // 孤立した点は処理解除
- for( k=2 ; k<153598 ; k+=2 )
- {
- if( (DWORD( rbuf+k ) & 0x80008000) == 0x8000
- && (WORD( rbuf+k-2 ) & 0x8000) == 0 )
- {
- WORD( rbuf+k ) &= 0x7fff;
- WORD(pImageBuf+k) ^= 0xffff;
- }
- }
- // ページヘッダの作成
- int i;
- WORD(bbuf ) = 3; /* brock 数 */
- WORD(bbuf+2 ) = 0x1422; /* stosd brock */
- DWORD(bbuf+4 ) = 17; /* data size */
- WORD(bbuf+8 ) = 1; /* data 数 */
- DWORD(bbuf+10) = nCol + ( nCol << 16 ); /* data */
- WORD(bbuf+14 ) = 1; /* offset 数 */
- WORD(bbuf+16 ) = 0x0000; /* offset */
- WORD(bbuf+18 ) = 1; /* data 個数 */
- WORD(bbuf+20 ) = 0x0000; /* 下位 address */
- BYTE(bbuf+22 ) = 0xff; /* 長さ */
- WORD(bbuf+23 ) = 38400;
- i = 25;
- i = mov_save_stosw1( i ); /* stosw */
- // 再びくっついてる点は復活
- for( k=2 ; k<153598 ; k+=2 ){
- if( (DWORD( rbuf+k ) & 0x80008000) == 0x80000000
- || (DWORD( rbuf+k-2 ) & 0x80008000) == 0x8000 )
- {
- int a1,a2;
- a1 = WORD(pImageBuf+k);
- a2 = WORD(rbuf +k);
- if (mov_save_cmp_data(a1,a2,svar.rough) == 0
- && (a2 & 0x8000) == 0 )
- {
- WORD( rbuf+k ) = a2 | 0x8000; /* 処理印 */
- WORD( pImageBuf+k ) ^= 0xffff;
- }
- }
- }
- //
- i = mov_save_movsw( i ); /* movsw */
- pghead[0] = svar.frame; /* page page head */
- pghead[1] = i; /* dsize */
- pghead[2] = 0; /* ox,oy */
- pghead[3] = 0; /* wait & loop */
- pghead[4] = 0; /* リザーブ */
- pghead[5] = 0; /* sound data1 */
- pghead[6] = 0; /* sound data2 */
- pghead[7] = 0; /* sound data3 */
- if((fps=fopen( pszMovName, "r+b" )) == NULL )
- return 2;
- fread( hread, 256, 1, fps );
- fseek( fps, 256+DWORD(hread+8), SEEK_SET );
- fwrite( (char *)pghead, 32, 1, fps );
- fwrite( bbuf, i, 1, fps );
- temp = ferror( fps );
- fclose( fps );
- svar.total_byte += (i + 32);
- }
- else
- {
- /* 差分 */
- int i;
- i = 0; /* data counter */
- WORD( bbuf+i ) = 2;
- if( svar.premove )
- WORD( bbuf+i ) += 1;
- i+=2;
- if( svar.premove )
- {
- i = mov_save_movebox16( i );
- /* clearしてやり直す */
- for( y=svar.y0 ; y<=svar.y1 ; y++ ){
- for( x=svar.x0 ; x<=svar.x1 ; x++ ){
- // j = (y << 10) + (x << 1); /* vram */
- int k;
- int a1,a2;
- k = y*640 + x*2; /* rbuf */
- a1 = WORD(pImageBuf+k);
- a2 = WORD(rbuf +k);
- if( a1 & 0x8000 )
- WORD(pImageBuf + k) ^= 0xffff;
- if( a2 & 0x8000 )
- WORD( rbuf+k ) = a2 & 0x7fff;
- }
- }
- }
- /* フィルター */
- // if( svar[11] )mov_save_filter2( filtAdjust[ svar[11] ], svar, rbuf );
- /* check */
- for( y=svar.y0 ; y<=svar.y1 ; y++ ){
- for( x=svar.x0 ; x<=svar.x1 ; x++ ){
- int k,a1,a2;
- // j = (y << 10) + (x << 1); /* vram */
- k = y*640 + x*2; /* rbuf */
- a1 = WORD(pImageBuf+k);
- a2 = WORD( rbuf+k );
- if( mov_save_cmp_data( a1, a2, svar.rough ) == 0
- && (a2 & 0x8000) == 0 ){
- WORD( rbuf+k ) = a2 | 0x8000; /* 処理印 */
- WORD(pImageBuf+k) ^= 0xffff;
- }
- }
- }
- /* 孤立した点は処理解除 */
- int k;
- for( k=2 ; k<153598 ; k+=2 ){
- if( (DWORD( rbuf+k ) & 0x80008000) == 0x8000
- && (WORD( rbuf+k-2 ) & 0x8000) == 0 ){
- WORD( rbuf+k ) &= 0x7fff;
- // j = ( (k/640) << 10 ) + ( k % 640 );
- WORD(pImageBuf+k) ^= 0xffff;
- }
- }
-
- i = mov_save_stosw1( i ); /* stosw */
-
- /* 再びくっついてる点は復活 */
- for( k=2 ; k<153598 ; k+=2 ){
- if( (DWORD( rbuf+k ) & 0x80008000) == 0x80000000
- || (DWORD( rbuf+k-2 ) & 0x80008000) == 0x8000 ){
- // j = ( (k/640) << 10 ) + ( k % 640 );
- int a1,a2;
- a1 = WORD(pImageBuf+k);
- a2 = WORD( rbuf+k );
- if( mov_save_cmp_data( a1, a2, svar.rough ) == 0
- && (a2 & 0x8000) == 0 ){
- WORD( rbuf+k ) = a2 | 0x8000; /* 処理印 */
- WORD(pImageBuf+k) ^= 0xffff;
- }
- }
- }
-
- i = mov_save_movsw( i ); /* movsw */
- pghead[0] = svar.frame; /* page page head */
- pghead[1] = i; /* dsize */
- pghead[2] = 0; /* ox,oy */
- pghead[3] = 0; /* wait & loop */
- pghead[4] = 0; /* リザーブ */
- pghead[5] = 0; /* sound data1 */
- pghead[6] = 0; /* sound data2 */
- pghead[7] = 0; /* sound data3 */
- if( ( fps = fopen( pszMovName, "r+b" ) ) == NULL )
- return 2;
- fread( hread, 256, 1, fps );
- fseek( fps, 256+DWORD(hread+8), SEEK_SET );
- fwrite( (char *)pghead, 32, 1, fps );
- fwrite( bbuf, i, 1, fps );
- temp = ferror( fps );
- fclose( fps );
- svar.total_byte += i + 32;
- }
-
- svar.frame++;
- if( temp ){
- /* remove( namemov ); disk full */
- return 2;
- }
- return mov_save_end( pszMovName );
- }
-
- /*--------------------------------------------------------*/
- /* MOVヘッダの読み込み(追加保存のため) */
- /*--------------------------------------------------------*/
-
- int mov_head_read(char *pszMovName)
- {
- FILE *fp;
- int n, temp, page, size;
- char head[256];
-
- if ((fp = fopen( pszMovName, "rb")) == NULL)
- return 1;
- temp = fread( head, 256, 1, fp );
- if (temp < 1)
- goto movh10;
- // MOVヘッダであるかどうか確認
- if (DWORD(head+0 ) != 0x32564f4d )
- goto movh10;
- if (DWORD(head+4 ) != 16 )
- goto movh10;
- if (DWORD(head+16) != 320 )
- goto movh10;
- if (DWORD(head+20) != 240 )
- goto movh10;
- svar.frame = DWORD( head+12 );
- svar.total_byte = DWORD( head+ 8 );
- svar.x0 = WORD( head + 32 ); /* 録画領域 */
- svar.y0 = WORD( head + 34 );
- svar.x1 = WORD( head + 36 );
- svar.y1 = WORD( head + 38 );
- fclose( fp );
- return 0;
- movh10:
- fclose( fp );
- return 58;
- }
-
- /*--------------------------------------------------------*/
- /* MOVファイルの作成 */
- /*--------------------------------------------------------*/
-
- int mov_save( char *pszMovName, int nTotalFrame,
- int (*pfnLoadFrame)(char*,int,int*,int*),
- int (*pfnCheckFrame)(int),
- MOVPARA *para)
- // 返り値:-2 メモリ不足
- {
- int err;
- err = 0;
- // 画像読み込みバッファを確保
- if ((pImageBuf = MALLOC(320*240*2)) == NULL)
- return -2;
- if ((rbuf = MALLOC(153600)) == NULL )
- {
- FREE(pImageBuf);
- return -2;
- }
- if ((bbuf = MALLOC(524288)) == NULL )
- {
- FREE(rbuf);
- FREE(pImageBuf);
- return -2;
- }
- // パラメータ設定
- if (!para->add)
- {
- svar.frame = 0 ;
- svar.total_byte = 0 ;
- }
- else
- {
- if ((err = mov_head_read(pszMovName)) != 0)
- goto END;
- }
- svar.rough = para->rough;
- svar.premove = (para->premove ? 1 : 0) * 8 ;
- svar.soft = para->soft;
- svar.wait = para->wait;
-
- // 新規作成の場合、フレームの縦横ドット数を得る
- if ( nTotalFrame > 0 && svar.frame == 0 )
- {
- svar.x0 = 0 ;
- svar.y0 = 0 ;
- svar.x1 = 319;
- svar.y1 = 239;
- int ret = (*pfnLoadFrame)( pImageBuf, 0, &nFrameWid, &nFrameHt );
- if (ret == 0)
- {
- svar.x1 = _min(319, nFrameWid - 1);
- svar.y1 = _min(239, nFrameHt - 1);
- }
- }
- // 各フレームについて圧縮保存
- int iFrame;
- for (iFrame = 0; iFrame < nTotalFrame; iFrame++)
- {
- if (pfnCheckFrame != 0)
- (*pfnCheckFrame)(iFrame);
- int ret;
- ret = (*pfnLoadFrame)(pImageBuf,iFrame,NULL,NULL);
- if (ret == 0) {
- if ((err = mov_save_page(pszMovName)) != 0)
- goto END;
- // memcpy(pImageBuf, rbuf, 320*240*2);
- // フィルタ処理後の画像を画面に表示??
- }
- // マウスのクリック(中止)のチェックをここでする
- }
- END:
- FREE(bbuf);
- FREE(rbuf);
- FREE(pImageBuf);
- return err;
- }
-